class NavMesh {
    public areas: number[]
    public indices: number[]
    public vertices: NavPos[]
}
class NavPos {
    public x: number
    public y: number
    public z: number
}
class TiledMap {
    public width: number
    public height: number
}
class NavPoly {
    private static _sequenceId: number = 0
    public id: number
    public vertices: NavPos[] = []
    public neighbour: { [idx: number]: boolean } = {}
    constructor() {
        this.id = NavPoly._sequenceId++
    }
}
class NavScene {
    public static Instance: NavScene
    constructor(stage: egret.Stage) {
        this._stage = stage
        this._stage.addChild(this._root)
        NavScene.Instance = this
    }

    private _root: egret.DisplayObjectContainer = new egret.DisplayObjectContainer()
    private _stage: egret.Stage
    private _map: egret.DisplayObject
    private _mesh: egret.DisplayObjectContainer = new egret.DisplayObjectContainer()

    private _move: { startX: number, startY: number, orgX: number, orgY: number }
    private _polygens: { [idx: number]: NavPoly } = {}

    public init() {
        this._map = new egret.Bitmap(RES.getRes("map_5_jpg"))
        this._root.width = this._map.width
        this._root.height = this._map.height
        this._root.addChild(this._map)

        this._map.touchEnabled = false
        this._root.touchEnabled = true
        this._root.addEventListener(egret.TouchEvent.TOUCH_BEGIN, this.touchBeginRoot, this)
        this._root.addEventListener(egret.TouchEvent.TOUCH_MOVE, this.touchMoveRoot, this)
        this._root.addEventListener(egret.TouchEvent.TOUCH_END, this.touchEndRoot, this)
        this._root.addEventListener(egret.TouchEvent.TOUCH_CANCEL, this.touchEndRoot, this)
        this._root.addEventListener(egret.TouchEvent.TOUCH_RELEASE_OUTSIDE, this.touchEndRoot, this)

        {
            let tiled: TiledMap = RES.getRes("map_17_json")
            let scalePos = (p: NavPos): NavPos => {
                let n = new NavPos()
                n.x = Math.ceil(p.x / (tiled.width * 32 / this._map.width))
                n.z = Math.ceil(p.z / (tiled.height * 16 / this._map.height))
                return n
            }
            this._root.addChild(this._mesh)
            this._mesh.width = this._map.width
            this._mesh.height = this._map.height
            this._mesh.x = this._mesh.width / 2
            this._mesh.y = this._mesh.height / 2
            this._mesh.anchorOffsetX = this._mesh.width / 2
            this._mesh.anchorOffsetY = this._mesh.height / 2
            let naviMesh: NavMesh = RES.getRes("map_17.navmesh_json")
            // console.log(naviMesh.areas)
            // console.log(naviMesh.vertices)
            // console.log(naviMesh.indices)
            let g = new egret.Shape()
            this._mesh.addChild(g)
            g.graphics.lineStyle(1, 0x00CA00);
            let indices = 0
            let vex: { x: number, y: number, z: number }
            let edges: { [idx: string]: number[] } = {}
            for (let i = 0; i < naviMesh.indices.length;) {
                let poly = new NavPoly()
                vex = scalePos(naviMesh.vertices[naviMesh.indices[i]])
                poly.vertices.push(vex)
                i++

                vex = scalePos(naviMesh.vertices[naviMesh.indices[i]])
                poly.vertices.push(vex)
                i++

                vex = scalePos(naviMesh.vertices[naviMesh.indices[i]])
                poly.vertices.push(vex)
                i++

                this._polygens[poly.id] = poly
                let make_neighbour = (a: NavPos, b: NavPos) => {
                    let k1 = a.x + "-" + a.y
                    let k2 = b.x + "-" + b.y
                    let key = a.x < b.x ? (k1 + "*" + k2) : (k2 + "*" + k1)
                    if (!edges[key]) {
                        edges[key] = []
                    }
                    edges[key].push(poly.id)
                }
                make_neighbour(poly.vertices[0], poly.vertices[1])
                make_neighbour(poly.vertices[0], poly.vertices[2])
                make_neighbour(poly.vertices[1], poly.vertices[2])

                g.graphics.beginFill(0x000280, 0.3)
                g.graphics.moveTo(poly.vertices[0].x, poly.vertices[0].z)
                g.graphics.lineTo(poly.vertices[1].x, poly.vertices[1].z)
                g.graphics.lineTo(poly.vertices[2].x, poly.vertices[2].z)
                g.graphics.endFill()
            }
            for (const key in edges) {
                if (Object.prototype.hasOwnProperty.call(edges, key)) {
                    edges[key].forEach((e1: number) => {
                        let poly = this._polygens[e1]
                        edges[key].forEach((e2: number) => {
                            if (poly.id != e2) {
                                poly.neighbour[e2] = true
                            }
                        })
                    })

                }
            }
            for (const key in this._polygens) {
                if (Object.prototype.hasOwnProperty.call(this._polygens, key)) {
                    let poly = this._polygens[key]
                    if (Object.keys(poly.neighbour).length < 1) {
                        console.warn("居然后孤立的多边形" + poly)
                        g.graphics.beginFill(0xA00280, 0.8)
                        g.graphics.moveTo(poly.vertices[0].x, poly.vertices[0].z)
                        g.graphics.lineTo(poly.vertices[1].x, poly.vertices[1].z)
                        g.graphics.lineTo(poly.vertices[2].x, poly.vertices[2].z)
                        g.graphics.endFill()
                    }
                }
            }
        }
    }

    private touchBeginRoot(evt: egret.TouchEvent) {
        // console.log(evt)
        this._move = {
            startX: evt.localX,
            startY: evt.localY,
            orgX: this._root.x,
            orgY: this._root.y,
        }
    }
    private touchMoveRoot(evt: egret.TouchEvent) {
        // console.log(evt)
        if (this._move) {
            let deltaX = evt.localX - this._move.startX
            let deltaY = evt.localY - this._move.startY
            this._root.x = this._move.orgX + deltaX
            this._root.y = this._move.orgY + deltaY
        }
    }
    private touchEndRoot(evt: egret.TouchEvent) {
        this._move = null
    }
}